package com.darren.archive.controller;

import com.alibaba.fastjson.JSONObject;
import com.darren.archive.component.SysParameterHelper;
import com.darren.archive.entity.LoginRecord;
import com.darren.archive.entity.LoginRecord.LoginType;
import com.darren.archive.entity.SysUser;
import com.darren.archive.repository.SysUserRepository;
import com.darren.archive.service.LoginRecordService;
import com.darren.archive.service.SysUserService;
import com.darren.framework.Exception.ArchiveException;
import com.darren.framework.bean.ResponseBean;
import com.darren.framework.controller.BaseController;
import com.darren.framework.entity.AppSession;
import com.darren.framework.entity.TokenEntity;
import com.darren.framework.utils.Constant;
import com.darren.framework.utils.EncryptAESUtil;
import com.darren.framework.utils.JWTUtil;
import com.darren.framework.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Api(value = "系统用户", tags = "系统用户接口", description = "系统用户接口")
@Controller
public class SysUserController extends BaseController {

    private Logger logger = LogManager.getLogger(SysUserController.class);

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private LoginRecordService loginRecordService;


    @GetMapping("/login")
    public String showSelectProduct(HttpServletRequest request) {

        return "/backend/login";
    }

    /**
     * 用户登陆接口
     *
     * @param userName 用户名
     * @param password 用户密码
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "用户名", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "password", value = "用户密码", required = true, paramType = "query", dataType = "String")
    })
    @ApiOperation(value = "用户登陆", notes = "用户登陆接口")
    @ResponseBody
    @PostMapping(value = "/sys/user/login")
    public ResponseBean login(@RequestParam(name = "userName", required = false) String userName,
                              @RequestParam(name = "password", required = false) String password) {
        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)) {
            throw new ArchiveException("用户名和者密码不能为空。");
        } else {
            SysUser sysUser = sysUserService.findByUserAccountOrMobile(userName);
            password = EncryptAESUtil.getEncryption(password, SysParameterHelper.getEncryptKey());
            if (sysUser == null) {
                throw new ArchiveException("用户不存在。");
            } else if (!password.trim().equals(sysUser.getPassword())) {
                throw new ArchiveException("密码不正确，请核对后再登陆。");
            } else if (sysUser.isEnable() == false && sysUser.isEditable()) {
                throw new ArchiveException(String.format("帐户【%s】已被禁用，请联系管理员。",sysUser.getUserAccount()));
            } else {
                LoginRecord loginRecord = new LoginRecord();
                loginRecord.setLoginId(sysUser.getId());
                loginRecord.setUserAccount(sysUser.getUserAccount());
                loginRecord.setLoginTime(new Date());
                loginRecord.setLoginType(LoginType.USER.getDescription());
                loginRecord.setExpiredTime(JWTUtil.getAccessExpired());
                loginRecord.setDelete(false);

                loginRecord = loginRecordService.save(loginRecord);
                TokenEntity tokenEntity = new TokenEntity(loginRecord.getId());
                String accessToken = JWTUtil.signAccessJWT(tokenEntity);
                String refreshToken = JWTUtil.signRefreshJWT(tokenEntity);
                Long expires_in = JWTUtil.getAccessExpired();

                AppSession appSession = new AppSession();
                appSession.setAttribute(Constant.ACCESS_TOKEN, accessToken);
                appSession.setAttribute(Constant.REFRESH_TOKEN, refreshToken);
                try {
                    loginRecord.setApplicationSession(appSession);
                    loginRecord = loginRecordService.update(loginRecord);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
                getResponse().setHeader(Constant.ACCESS_TOKEN, accessToken);
                getResponse().setHeader(Constant.REFRESH_TOKEN, refreshToken);
                return ResponseBean.isOk(sysUser);
            }
        }
    }


    /**
     * 根据用户姓名模糊查找用户
     *
     * @param name     用户姓名
     * @param pageNum  页号
     * @param pageSize 页大小
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "用户姓名", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "pageNum", value = "页号", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "页大小", paramType = "query", dataType = "Integer")
    })
    @ApiOperation(value = "查询用户", notes = "根据用户姓名模糊查找用户")
    @ResponseBody
    @RequiresPermissions("user:view")
    @GetMapping(value = "/sys/user/list")
    public ResponseBean getList(@RequestParam(name = "name", required = false) String name,
                                 @RequestParam(name = "pageNum", required = false, defaultValue = "0") Integer pageNum,
                                 @RequestParam(name = "pageSize", required = false, defaultValue = Constant.PAGE_SIZE_STRING) Integer pageSize) {
        Sort sort = new Sort(Sort.Direction.ASC, "name"); //创建时间降序排序
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        if (StringUtils.isEmpty(name)) {
            return ResponseBean.isOk(sysUserService.findAll(pageable));
        }
        return ResponseBean.isOk(sysUserService.findByNameLike("%" + name + "%", pageable));
    }


    /**
     * 根据用户姓名模糊查找用户
     *
     * @param name     用户姓名
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "用户姓名", paramType = "query", dataType = "String")
    })
    @ApiOperation(value = "查询用户", notes = "根据用户姓名模糊查找用户")
    @ResponseBody
    @RequiresPermissions("user:view")
    @GetMapping(value = "/sys/user/name/list")
    public ResponseBean getList(@RequestParam(name = "name", required = false) String name) {
        name = StringUtils.isEmpty(name)?"":name;
        return ResponseBean.isOk(sysUserService.findByNameLike("%" + name + "%"));
    }


    /**
     * 保存用户信息
     *
     * @param record 用户信息
     * @return
     */
    @ResponseBody
    @RequiresPermissions("user:edit")
    @ApiOperation(value = "保存用户信息", notes = "保存用户信息 SysUser，如果 id 为空，则新增；id 不为空，则修改")
    @PostMapping(value = "/sys/user/save", consumes = "application/json;charset=UTF-8")
    public ResponseBean save(@RequestBody @ApiParam(name = "保存用户信息", value = "传入json格式", required = true) SysUser record) {
        return ResponseBean.isOk(sysUserService.save(record));
    }


    /**
     * 修改用户密码
     *
     * @param record
     * @return
     */
    @ResponseBody
    @RequiresPermissions("user:edit")
    @ApiOperation(value = "修改用户密码", notes = "修改用户密码, 需要传入 json 对象，对象信息包括：用户id、旧密码 oldPassword、新密码 newPassword，且都是必填。如：{\"id\":1,\"oldPassword\":\"123456\",\"newPassword\":\"abcdef\"}")
    @PostMapping(value = "/sys/user/password/update", consumes = "application/json;charset=UTF-8")
    public ResponseBean updatePassword(@RequestBody @ApiParam(name = "用户id、旧密码 oldPassword、新密码 password", value = "传入json格式", required = true) JSONObject record) {
        return ResponseBean.isOk(sysUserService.updatePassword(record.getLong("id"),record.getString("oldPassword"),record.getString("newPassword")));
    }

    /**
     * 重置用户密码
     * @param id
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id", required = true, paramType = "path", dataType = "Long")
    })
    @ResponseBody
    @ApiOperation(value = "重置用户密码", notes = "重置用户密码, 需要传入 用户 id 。")
    @RequiresPermissions("user:edit")
    @PostMapping(value = "/sys/user/password/reset/{id}")
    public ResponseBean resetPassword(@PathVariable(name = "id") Long id) {
        return ResponseBean.isOk(sysUserService.resetPassword(id));
    }

    /**
     * 根据id 删除 用户信息
     * @param id
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id", required = true, paramType = "path", dataType = "Long")
    })
    @ResponseBody
    @RequiresPermissions("user:delete")
    @ApiOperation(value = "根据id 删除 用户信息", notes = "根据id 删除 用户信息")
    @DeleteMapping(value = "/sys/user/{id}")
    public ResponseBean deleteById(@PathVariable(name = "id") Long id) {
        sysUserService.deleteById(id);
        return ResponseBean.isOk();
    }


    /**
     * 根据id 查询 用户信息
     * @param id
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id", required = true, paramType = "path", dataType = "Long")
    })
    @ResponseBody
    @RequiresPermissions("user:view")
    @ApiOperation(value = "根据id 查询 用户信息", notes = "根据id 查询 用户信息")
    @GetMapping(value = "/sys/user/{id}")
    public ResponseBean getById(@PathVariable(name = "id") Long id) {
        return ResponseBean.isOk(sysUserService.findById(id));
    }


    /**
     * 保存是否启用状态
     *
     * @param record 用户信息
     * @return
     */
    @ResponseBody
    @RequiresPermissions("user:edit")
    @ApiOperation(value = "保存是否启用状态", notes = "保存是否启用状态")
    @PostMapping(value = "/sys/user/enable/save", consumes = "application/json;charset=UTF-8")
    public ResponseBean saveEnable(@RequestBody @ApiParam(name = "用户信息", value = "传入json格式", required = true) SysUser record) {
        return ResponseBean.isOk(sysUserService.saveEnable(record));
    }

}
